/* model */
const { getModuleTreeKeys } = require('../model/moduleTree')
const BuildOption = require('../model/BuildOption')
/* inquirer */
const inquirer = require('inquirer')
const TreePrompt = require('./inquirer-tree-prompt');
inquirer.registerPrompt('tree', TreePrompt);
/* util */
const colors = require('colors')
const { getGitLogFiftyCount, getLocalBranches } = require('./git')
const { formatGitLogsWithInquirer } = require('./format')
const { getModulesOriginKeys } = require('./get-modules-origin-keys')
const generateProjectTree = require('./generate-project-tree')

const esbuildList = {
  'yes': 'YES', 
  'no': 'NO'
}

const updateProjectTreeList = {
  'yes': 'YES', 
  'no': 'NO'
}

const moduleBuildType = {
  'full': '全量构建打包',
  'moduleManual': '按模块构建打包 + 手动选择',
  'moduleAutoBranch': '按模块构建打包 + 自动计算 + 分支模式',
  'moduleAutoCommit': '按模块构建打包 + 自动计算 + 按提交信息'
}

const esBuildPromptList = [
  {
    type: 'list',
    name: 'type',
    message: '请选择是否使用 esbuild 构建js,ts ?  (ps: 测试、预发可以使用，生产环境暂不推荐!!!) ',
    choices: getObjectValues(esbuildList)
  }
]

const moduleBuildTypePromptList = [
  {
    type: 'list',
    name: 'type',
    message: '请选择构建打包方式',
    choices: getObjectValues(moduleBuildType)
  }
]

const moduleBuildManualPromptList = [
  {
    type: 'tree',
    message: '请选择构建的模块名称: ',
    name: 'modules',
    multiple: true,
    pageSize: 23,
    tree: getModuleTreeKeys()
  }
]

const updateProjectTreePromptList = [
  {
    type: 'list',
    name: 'type',
    message: '请选择是否更新文件依赖数据 ? (ps: 当有文件增加或删除时需更新！) ',
    choices: getObjectValues(updateProjectTreeList)
  }
]

function getGitBranchPromptList(branches) {
  return [
    {
      type: 'list',
      name: 'branch',
      message: '请选择基于哪个分支构建',
      choices: branches
    }
  ]
}

function getGitLogsPromptList(logs) {
  return [
    {
      type: 'list',
      name: 'log',
      message: '请选择基于哪个提交构建 (默认只取最近50个提交)',
      choices: logs
    }
  ]
}

function getObjectValues(object) {
  return Object.keys(object).map(key => object[key])
}

/**
 * @description 是否使用esbuild
 */
function isUseEsBuild(data) {
  return data.type == esbuildList.yes
}

/**
 * @description 是否为全量构建
 */
function isFullBuild(data) {
  return data.type == moduleBuildType.full
}

/**
 * @description 是否为按模块依赖构建 基于分支
 */
function isModuleAutoBranchBuild(data) {
  return data.type == moduleBuildType.moduleAutoBranch
}

/**
 * @description 是否为按模块依赖构建 基于提交
 */
function isModuleAutoCommitBuild(data) {
  return data.type == moduleBuildType.moduleAutoCommit
}

/**
 * @description 是否为按模块手动选择构建
 */
function isModuleManualBuild(data) {
  return data.type == moduleBuildType.moduleManual
}

/**
 * @description 是否更新文件依赖数据
 */
function isUpdateProjectTree(data) {
  return data.type == updateProjectTreeList.yes
}

async function getBuildOptionWithInquirer() {
  // 构建配置
  let buildOption = new BuildOption()
  
  try {
    // FIXME: es-build-loader 暂时存在问题放在此项目中, 后面修改
    // esbuildLog()
    // const esbuildAnswersData = await inquirer.prompt(esBuildPromptList)
    // // 使用esbuild
    // if (isUseEsBuild(esbuildAnswersData)) {
    //   buildOption.isUseEsBuild = true
    // }
    
    moduleBuildLog()
    const modulesBuildTypeAnswersData = await inquirer.prompt(moduleBuildTypePromptList)
    // 是否为全量构建
    if (isFullBuild(modulesBuildTypeAnswersData)) {
      buildOption.isFullBuild = true
      return buildOption
    }
    
    // 修改配置状态为按模块构建
    buildOption.isModuleBuild = true
    
    // 是否为按模块手动选择构建
    if (isModuleManualBuild(modulesBuildTypeAnswersData)) {
      moduleBuildManualPromptLog()
      const modulesBuildManualAnswersData = await inquirer.prompt(moduleBuildManualPromptList)
      
      buildOption.moduleBuildOptions.isModuleManualBuild = true
      buildOption.moduleBuildOptions.modulesManualKeys = getModulesOriginKeys(modulesBuildManualAnswersData.modules)
      
      return buildOption
    }
    
    updateTreeLog()
    const updateProjectTreeAnswersData = await inquirer.prompt(updateProjectTreePromptList)
    if (isUpdateProjectTree(updateProjectTreeAnswersData)) {
      await generateProjectTree()
    }
    
    // 修改配置状态为按模块自动分析构建
    buildOption.moduleBuildOptions.isModuleAutoBuild = true
    
    // 按模块依赖构建 基于分支
    if (isModuleAutoBranchBuild(modulesBuildTypeAnswersData)) {
      const branches = getLocalBranches(true)
      const branchAnswersData = await inquirer.prompt(getGitBranchPromptList(branches))
      const branch = branchAnswersData.branch
      
      buildOption.moduleBuildOptions.moduleAutoBuildOption.branch = branch
      buildOption.moduleBuildOptions.moduleAutoBuildOption.isBranch = true
      
      return buildOption
    }
    
    // 按模块依赖构建 基于提交记录
    if (isModuleAutoCommitBuild(modulesBuildTypeAnswersData)) {
      const gitLogsString = getGitLogFiftyCount()
      const { logMap } = formatGitLogsWithInquirer(gitLogsString)
      const logsAnswersData = await inquirer.prompt(getGitLogsPromptList(Object.keys(logMap)))
      const commit = logMap[logsAnswersData.log].commit
      
      buildOption.moduleBuildOptions.moduleAutoBuildOption.commit = commit
      buildOption.moduleBuildOptions.moduleAutoBuildOption.isCommit = true
      
      return buildOption
    }
    
    return buildOption
    
  } catch (err) {
    let buildOptionForError = new BuildOption()
    buildOptionForError.isFullBuild = true
    
    console.error(err)
    
    return buildOptionForError
  }
}

function esbuildLog() {
  console.log(colors.green(`
    详情查看：
    https://github.com/privatenumber/esbuild-loader
    https://esbuild.github.io/ 
  `))
}

function moduleBuildLog() {
  console.log(colors.red(`
    如选择【按模块构建打包 + 手动选择】请确认知晓需要构建哪些模块 !!!!
    修改入口js (entry.js) 有关引用的建议全量打包。
  `))
}

function moduleBuildManualPromptLog() {
  console.log(colors.green(`
  使用箭头按键移动，上下键移动，右键展开子模块，左键收起子模块，
  空格键选择，
  回车键确认。
  `))
}

function updateTreeLog() {
  console.log(colors.green(`
    详情查看：
    https://github.com/pahen/madge
    使用第三库生成依赖信息，根据文件改动找到对应的依赖，直到入口文件
  `))
  
  console.log(colors.red(`
    目前处于实验阶段 !
  `))
}

module.exports = getBuildOptionWithInquirer
